package com.laopan.wxpay.request.certificates;

import com.laopan.wxpay.WxConstants;
import com.laopan.wxpay.bean.certificate.MerchantPrivateKey;
import com.laopan.wxpay.config.WxPayConfig;
import com.laopan.wxpay.exception.WxPayException;
import com.laopan.wxpay.utils.PemUtils;

import java.security.PrivateKey;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 默认的微信api私钥
 *
 * @author laopan
 * @className DefaultPrivateKeyManager
 * @date 2021/2/22 17:48
 */

public class DefaultPrivateKeyManager implements PrivateKeyManager {
    /**
     * 在resource的路径
     */
    private String privateRootPath;

    /**
     * 商户ApiV3key
     */

    private String apiV3Key;
    /**
     * 商户证书的序列号
     */
    private String serialNo;

    private final static Map<String, PrivateKey> PRIVATE_KEY = new ConcurrentHashMap<>();

    private final Object lock = new Object();

    public DefaultPrivateKeyManager(WxPayConfig wxPayConfig) {
        this.apiV3Key = wxPayConfig.getApiV3Key();
        this.serialNo = wxPayConfig.getSerialNo();
    }

    public DefaultPrivateKeyManager setPrivateKeyPath(String privateRootPath) {
        this.privateRootPath = privateRootPath;
        return this;
    }

    @Override
    public MerchantPrivateKey getPrivateKey(String mchId) {
        if (mchId == null || mchId.trim().length() == 0) {
            throw new IllegalArgumentException("参数错误,商户id不能为空");
        }
        if (this.serialNo == null || this.serialNo.trim().length() == 0) {
            throw new IllegalArgumentException("参数错误,商户api序列号不能为空");
        }
        if (this.apiV3Key == null || this.apiV3Key.trim().length() == 0) {
            throw new IllegalArgumentException("参数错误,商户apiV3Key不能为空");
        }
        PrivateKey privateKey = PRIVATE_KEY.get(mchId);
        if (privateKey == null) {
            synchronized (lock) {
                privateKey = PRIVATE_KEY.get(mchId);
                if (privateKey == null) {
                    privateKey = loadPrivateKey(mchId);
                    PRIVATE_KEY.putIfAbsent(mchId, privateKey);
                }
            }
        }
        return new MerchantPrivateKey(mchId, privateKey, this.serialNo, this.apiV3Key);
    }

    private PrivateKey loadPrivateKey(String mchId) {
        String privatePath = PemUtils.getMerPath(mchId, this.privateRootPath, WxConstants.PRIVATE_KEY_SUFFIX);
        try {
            PrivateKey privateKey = PemUtils.loadPrivateKey(privatePath);
            if (privateKey == null) {
                throw new WxPayException("微信支付私钥为空");
            }
            return privateKey;
        } catch (Exception e) {
            throw new WxPayException(e.getMessage());
        }
    }
}
